#!/usr/bin/python

import sys;
import ply.lex as lex;
import ply.yacc as yacc;

mem_i = 1; # numer kolejnej zmiennej
variables = {} # globalna tablica do wyrazen arytmetycznych

class Node:
    left , right, value = None, None, 0
    
    def __init__(self, left, right, value):
        self.left = left
        self.right = right
        self.value = value
        self.nodetype = None
        self.name = None
        self.lineno = None

class NodeArithm(Node):
    '''
    Wyrazenie arytmetyczne
    '''
    def __init__(self, left, right, operator):
        super(NodeArithm, .__init__(left, right, operator)
    def eval(self):
        global i
#        global line
        self.var_name = 'mem'+str(i)
        # dodanie wpisu do tablicy
        
        # operator | arg1 | arg2 | nazwa_zmiennej_tymczasowej
        variables[self.var_name] = (self.value, self.left, self.right)
#        line += 1
        i = i+1
        self.code = '%i: %s = %s %s %s' % (line, self.var_name, variables[self.var_name][1], variables[self.var_name][0], variables[self.var_name][2])
        return self.code;


class NodeAssign(Node):
    '''
    Instrukcja przypisania
    '''
    def eval(self):
        global i
        # = | wartosc | | zmienna
        variables[self.left] = ('=', self.right, '')
        i = i+1
        self.code = '%i: %s = %s' % (line, self.left, variables[self.left][1])
        return self.code;

class NodeInstructions(Node):
    '''
    Zestaw instrukcji wszystkich typow
    '''
    def eval(self):
        global i
        return '%s\n%s\n' % (self.left, self.right)
    
#        p[0] = na

literals = "{}()<>=;+-*/"

tokens = ( "ID", "NUMBER", "IF",  "ELSE", "EQ", "NEQ", "LE", "GE" );

t_ignore = ' \t'

def t_newline(t):
    r'\n+'
    t.lexer.lineno += len(t.value)

def t_error(t):
    print("Illegal character %s" % t.value[0])
    t.lexer.skip(1)


def t_NUMBER(t):
    r"\d+(\.\d*)?|\.\d+"
    t.value = float(t.value)
    return t

def t_IF(t):
    "if"
    return t

def t_ELSE(t):
    "else"
    return t

def t_LE(t):
    r"<="
    return t

def t_GE(t):
    r">="
    return t

def t_EQ(t):
    r"=="
    return t

def t_NEQ(t):
    r"!="
    return t

def t_ID(t):
    r"[a-zA-Z_]\w*"
    return t


precedence = (
   ("nonassoc", 'IFX'),
   ("nonassoc", 'ELSE'),
   ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
   ("left", '+', '-'),
   ("left", '*', '/') )


# pamiec zmiennych i memow

line = 1
i = 1
variables = {}


def p_error(p):
    print("Syntax error at token", p.type)

def p_program(p):
    """program : instructions"""


def p_instructions(p):
    """instructions : instructions instruction
                    | instruction"""
    


def p_instruction(p):
    """instruction : assignment
                   | choice_instr"""
    

def p_assignment(p):
    """assignment : ID '=' expression ';' """

    
    
def p_expression(p):
    """expression : NUMBER
                  | ID
                  """
#    p[0] = Node(None, None, p[1], None)
              

def p_expression_dz(p):
    """expression : expression '+' expression
                  | expression '-' expression
                  | expression '*' expression
                  | expression '/' expression
    """
#    p[0] = Node(p[1],p[3],None, )
    
def p_expression_na(p):
    """ expression : '(' expression ')' """
    p[0]=p[2]


def p_choice_instr(p):
    """choice_instr : IF '(' condition ')' stmt %prec IFX
                    | IF '(' condition ')' stmt ELSE stmt """


def p_condition(p):
    """condition : expression EQ  expression
                 | expression NEQ expression
                 | expression GE  expression
                 | expression LE  expression
                 | expression '<' expression
                 | expression '>' expression """

def p_stmt(p):
    """stmt : assignment
            | '{' instructions '}'
            | choice_instr """


if len(sys.argv)>1:
    file = open(sys.argv[1], "r");
else:
    file = open("example2.txt", "r");


lexer = lex.lex()
parser = yacc.yacc()
text = file.read()
parser.parse(text, lexer=lexer)
